Namespace.Use("Application.UI.Page.Sensors", function(ns) {
    //
    //  Imports.
    //
    var Sensor = Namespace.Import("Application.Sensor");
    var Net = Namespace.Import("Application.Net");
    var UI = Namespace.Import("UI");

    //
    //  Constants.
    //
    var cst_PagePadding = 8;

    //
    //  Global.
    //
    var g_Pages = [];

    //
    //  Public APIs.
    //
    function CreateSensorPage(title, track_time, adapters) {
        var datasets = [];

        //  Get all data-sets.
        adapters.forEach(function(adapter) {
            adapter.GetDataSets().forEach(function(dataset) {
                datasets.push(dataset);
            });
        });

        //  Create the chart.
        var chart = new Sensor.Interface.Object.WaveformChart(
            title, track_time, datasets, Sensor.Configuration.GetRefreshInterval()
        );

        //  Add callbacks.
        var offset = 0;
        adapters.forEach(function(adapter) {
            var ds = adapter.GetDataSets();
            adapter.AddDataCallback((function(_ofx) {
                return function(_data) {
                    for (var idx = 0; idx < _data.Values.length; ++idx) {
                        chart.PutData(_ofx + idx, _data.Time, _data.Values[idx]);
                    }
                };
            })(offset));
            offset += ds.length;
        });

        //  Subscribe data.
        Net.Core.AddCallback(function(msg) {
            msg.forEach(function(item) {
                if(item["type"] == "Monitor"){
                    var routes = [];
                    for (var idx = item.range[0]; idx <= item.range[1]; ++idx) {
                        routes.push(idx);
                    }
                    adapters.forEach(function(adapter) {
                        adapter.ReceiveData(item["device"], routes, item["value"], item["time"]);
                    });
                }

            });
        });

        //  Create the page.
        var page = new UI.Object.PaddingContainer(cst_PagePadding);
        page.AddChild(chart);

        return page;
    }

    function CreateFFTPage(title, track_time, adapters,interval) {
        var datasets = [];

        //  Get all data-sets.
        adapters.forEach(function(adapter) {
            adapter.GetDataSets().forEach(function(dataset) {
                datasets.push(dataset);
            });
        });

        //  Create the chart.
        var chart = new Sensor.Interface.Object.FFTChart(
            title, track_time, datasets, interval
        );

        //  Add callbacks.
//        var offset = 0;
//        adapters.forEach(function(adapter) {
//            var ds = adapter.GetDataSets();
//            adapter.AddDataCallback((function(_ofx) {
//                return function(_data) {
//                    for (var idx = 0; idx < _data.Values.length; ++idx) {
//                        chart.PutData(_ofx + idx, _data.Time, _data.Values[idx]);
//                    }
//                };
//            })(offset));
//            offset += ds.length;
//        });

        //  Subscribe data.
        Net.Core.AddCallback(function(msg) {
            if(msg.length>0){
                var item = msg[0];
                    if(item["device"] == "fft-data"){
                        console.info(item);
                        var data = item["data"];
                        chart.PutData(data["frequencies"],data["values"]);
                    }
            }

        });

        //  Create the page.
        var page = new UI.Object.PaddingContainer(cst_PagePadding);
        page.AddChild(chart);

        return page;
    }

    function GetPages() {
        return g_Pages;
    }

    //  Create pages.
    (function() {
        var type = Arg("type");
        var device = Arg("device");
        var track_time = Arg("time");
        var interval = Arg("interval");
        var title = Arg("title");

        if (device == "fft-data") {
            console.log("fuck fft...");
              var sensors = Sensor.Configuration.GetSensors();
            for (var sensor_type in sensors) {
                var track_time = sensors[sensor_type]["Time"];
                var adapters = sensors[sensor_type]["Adapters"];
                if(typeof(interval) == "undefined"){
                    interval = Sensor.Configuration.GetRefreshInterval();
                }
                console.log(interval);
                g_Pages.push({
                    "Object": CreateFFTPage(title, track_time, adapters,interval),
                    "Title": sensor_type
                });
            }
        } else if (device == "Monitor") {
            var sensors = Sensor.Configuration.GetSensors();
            for (var sensor_type in sensors) {
            if(typeof(track_time) == "undefined"){
                track_time = sensors[sensor_type]["Time"];
            }

                var adapters = sensors[sensor_type]["Adapters"];
                g_Pages.push({
                    "Object": CreateSensorPage(sensor_type, track_time, adapters),
                    "Title": sensor_type
                });
            }
        } else {
            console.error("No chart type specified.");
        }
    })();

    //  Export public APIs.
    Namespace.Export(ns, "GetPages", GetPages);
});
